package com.zt.english.player

import android.media.MediaPlayer
import android.os.Build

/**
 * 单个单词片段播放控制类
 */
class WordPlayerController : MediaPlayer.OnPreparedListener,MediaPlayer.OnErrorListener,MediaPlayer.OnCompletionListener{
    private var mPlayer:MediaPlayer?
    private lateinit var mPlaybackState : PlaybackState
    private var mCallbacks : Callbacks? = null

    init{
        mPlayer = MediaPlayer()
        //注册相关回调监听接口
        mPlayer?.run {
            setOnPreparedListener(this@WordPlayerController)
            setOnErrorListener(this@WordPlayerController)
            setOnCompletionListener(this@WordPlayerController)
        }
    }

    /**
     * 线程安全的单列懒汉式
     */
    companion object{
        private var instance:WordPlayerController?=null
            get() {
                if (field == null) {
                    field = WordPlayerController()
                }
                return field
            }
        //在Kotlin中，如果你需要将方法声明为同步，需要添加@Synchronized注解。
        @Synchronized
        fun get():WordPlayerController{
            return instance!!
        }
    }

    override fun onPrepared(mp: MediaPlayer?){
        if(!isPrepareMode){
            mp?.start()
            setPlaybackState(PlaybackState.PLAYBACK_STATE_PLAYING)
        }
        mCallbacks.let {
            mp?.run {
                duration.let {
                    mCallbacks?.run {
                        onAudioDataChanged(it)
                    }
                }
            }
        }
    }

    override fun onError(mp: MediaPlayer?, what: Int, extra: Int): Boolean {
        setPlaybackState(PlaybackState.PLAYBACK_STATE_ERROR)
        return false
    }

    override fun onCompletion(mp: MediaPlayer?) {
        if(mp!=null && !mp.isLooping){
            setPlaybackState(PlaybackState.PLAYBACK_STATE_COMPLETION)
        }
    }
    enum class PlaybackState{
        PLAYBACK_STATE_NONE,
        PLAYBACK_STATE_STOPPED,  // State indicating this item is currently stopped.
        PLAYBACK_STATE_PAUSED,   // State indicating this item is currently paused.
        PLAYBACK_STATE_PLAYING,  // State indicating this item is currently playing.
        PLAYBACK_STATE_COMPLETION,
        PLAYBACK_STATE_ERROR,
    }
    interface Callbacks {
        /**
         * Override to handle changes in playback state.
         *
         * @param state The new playback state of the session
         */
        fun onPlaybackStateChanged(state: PlaybackState?)

        /**
         * Override to handle changes to the current audio data.
         */
        fun onAudioDataChanged(duration: Int)
    }
    var isPrepareMode :Boolean = true
    /**
     * 准备播放数据,准备成功后需调用mPlayer?.start()方法进行播放
     */
    fun prepareAudioData(url:String){
        isPrepareMode = true
        mPlayer?.run {
            reset()//重置
            setDataSource(url)//设置播放地址
            prepareAsync()//异步装备，防止阻塞主线程
        }
    }
    /**
     * 准备加载播放
     */
    fun startPlay(url:String){
        isPrepareMode = false
        mPlayer?.run {
            reset()//重置
            setDataSource(url)//设置播放地址
            prepareAsync()//异步装备，防止阻塞主线程
        }
    }
    /**
     * 播放
     */
    fun play(){
        if(!mPlayer?.isPlaying()!!){
            mPlayer?.start()
            setPlaybackState(PlaybackState.PLAYBACK_STATE_PLAYING)
        }
    }
    /**
     * 暂停播放
     */
    fun pause(){
        mPlayer?.pause()
        setPlaybackState(PlaybackState.PLAYBACK_STATE_PAUSED)
    }

    /**
     * 停止播放
     */
    fun stop(){
        if(mPlayer!=null){
            mPlayer?.release()
            mPlayer = null
            setPlaybackState(PlaybackState.PLAYBACK_STATE_STOPPED)
        }
    }
    /**
     * 获取当前播放进度，返回毫秒值
     */
    fun getCurrentPosition():Int{
        return mPlayer?.currentPosition!!
    }
    /**
     *跳转到指定位置播放
     */
    fun seekToPosition(msec : Int){
        mPlayer?.seekTo(msec)
        play()
    }
    /**
     *设置是否循环播放
     */
    fun setLooping(isLoop : Boolean){
        (mPlayer?.isLooping) = isLoop
    }
    /**
     * 判断当前音频是否在播放中
     */
    fun isPlaying():Boolean{
        return mPlayer?.isPlaying?:false
    }
    /**
     * service destory时
     */
    fun destory(){
        stop()
        unregisterCallback()
    }
    /**
     * MediaPlayer相关播放状态监听回调
     */
    private fun setPlaybackState(playbackState: PlaybackState) {
        mPlaybackState = playbackState
        mCallbacks?.run {
            onPlaybackStateChanged(playbackState)
        }
    }
    fun registerCallback(callbacks: Callbacks) {
        mCallbacks = callbacks
    }
    fun unregisterCallback() {
        mCallbacks = null
    }

    // 设置音乐播放速度
    // IT老五(简书ThinkinLiu) http://itlao5.com
    fun changeplayerSpeed(speed: Float) {
        if (mPlayer == null)return
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // API 23 （6.0）以上 ，通过设置Speed改变音乐的播放速率
            if (mPlayer!!.isPlaying) {
                // 判断是否正在播放，未播放时，要在设置Speed后，暂停音乐播放
                mPlayer!!.playbackParams = mPlayer!!.playbackParams.setSpeed(speed)
            } else {
                mPlayer!!.playbackParams = mPlayer!!.playbackParams.setSpeed(speed)
                mPlayer!!.pause()
            }
        } else {
            // 在Android6.0以前，需要另想办法处理，后续查到好的方法再补充

        }
    }

}